// pkg/response/response.go
package response

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"fmt"
	"io"
	"mygin/config"
)

// PaginationResponse 通用分页响应结构
type PaginationResponse[T any] struct {
	Total      int64 `json:"total"`       // 总记录数
	Page       int   `json:"page"`        // 当前页码
	PageSize   int   `json:"page_size"`   // 每页数量
	TotalPages int   `json:"total_pages"` // 总页数
	Data       []T   `json:"data"`        // 数据列表
}

// NewPaginationResponse 创建分页响应
func NewPaginationResponse[T any](total int64, page, pageSize int, data []T) PaginationResponse[T] {
	return PaginationResponse[T]{
		Total:      total,
		Page:       page,
		PageSize:   pageSize,
		TotalPages: calculateTotalPages(total, pageSize),
		Data:       data,
	}
}

// calculateTotalPages 计算总页数
func calculateTotalPages(total int64, pageSize int) int {
	if pageSize == 0 {
		return 0
	}
	return int((total + int64(pageSize) - 1) / int64(pageSize))
}

func Success[T any](msg string, data ...T) SuccessResponse[T] {
	if msg == "" {
		msg = "success" // 默认消息
	}
	resp := SuccessResponse[T]{
		Code: 200,
		Msg:  msg,
	}
	// 如果有提供 data 参数
	if len(data) > 0 {
		resp.Data = &data[0] // 取第一个元素
	}
	return resp
}

// NewErrorRespoFailnse 创建错误响应
func Fail(code int, msg string, details ...string) ErrorResponse {
	if msg == "" {
		msg = "error" // 默认错误消息
	}

	errResp := ErrorResponse{
		Code: code,
		Msg:  msg,
	}

	// 如果有详情信息则添加
	if len(details) > 0 {
		errResp.Details = details[0]
	}
	return errResp
}

// 成功响应
type SuccessResponse[T any] struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data *T     `json:"data,omitempty"`
}

// 错误响应
type ErrorResponse struct {
	Code    int    `json:"code"`
	Msg     string `json:"msg"`
	Details string `json:"details,omitempty"`
}

// 加密
func EncryptAES(plaintext []byte) ([]byte, []byte, error) {
	key := config.GetAESKey() // 从配置获取密钥
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, nil, err
	}

	// 生成IV
	iv := make([]byte, aes.BlockSize)
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		return nil, nil, err
	}

	// PKCS7填充
	plaintext = pkcs7Pad(plaintext, aes.BlockSize)

	// 加密
	ciphertext := make([]byte, len(plaintext))
	mode := cipher.NewCBCEncrypter(block, iv)
	mode.CryptBlocks(ciphertext, plaintext)

	return ciphertext, iv, nil
}

// 解密
func DecryptAES(ciphertext []byte, iv []byte) ([]byte, error) {
	key := config.GetAESKey() // 从配置获取密钥
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}

	if len(ciphertext)%aes.BlockSize != 0 {
		return nil, fmt.Errorf("ciphertext is not a multiple of the block size")
	}

	// 解密
	mode := cipher.NewCBCDecrypter(block, iv)
	plaintext := make([]byte, len(ciphertext))
	mode.CryptBlocks(plaintext, ciphertext)

	// 去除PKCS7填充
	plaintext = pkcs7Unpad(plaintext)

	return plaintext, nil
}

func pkcs7Pad(data []byte, blockSize int) []byte {
	padding := blockSize - len(data)%blockSize
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(data, padText...)
}

func pkcs7Unpad(data []byte) []byte {
	length := len(data)
	unpadding := int(data[length-1])
	return data[:(length - unpadding)]
}
